package com.eryos.android.cigarettecounter;

/**
 * Project :  CigaretteCounter
 * Author :   Olivier Combe 
 * URL :      http://eryos.fr/CigaretteCounter/
 *
 * Copyright (C) 2011 - Olivier Combe 
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 *
 */

import java.io.IOException;
import java.math.BigDecimal;
import java.net.UnknownHostException;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Locale;
import java.util.TreeMap;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.Gallery;
import android.widget.ImageView;
import android.widget.TextView;

import com.eryos.android.cigarettecounter.beans.History;
import com.eryos.android.cigarettecounter.beans.SmokeAverage;
import com.eryos.android.cigarettecounter.beans.SmokeCounter;
import com.eryos.android.cigarettecounter.charts.Chart;
import com.eryos.android.cigarettecounter.charts.HistoChart;
import com.eryos.android.cigarettecounter.charts.LineChart;
import com.eryos.android.cigarettecounter.database.WeeklyAdapterImpl;
import com.eryos.android.cigarettecounter.tool.Tools;
import com.eryos.android.cigarettecounter.ui.ChartPopup;
 
public class HistoryActivity extends RootActivity {
 
    /** *************** UI Elements *************** **/	
    private TextView averageLabel;
    private TextView totalLabel;
    private TextView costLabel;
    private TextView historyTitle;
    private TextView chartTitle;
    private Gallery chartGallery;
    private ImageAdapter chartImageAdapter;

    private Button homeButton; 
    private Button showStatButton; 

    /** *************** Instance Variables *************** **/	
    private History type;

    private ArrayList<Chart> listOfCharts;

    private double 	average = -1;
    private double 	cost = -1;
    private int 	total = -1;

    private WeeklyAdapterImpl weeklyDb;
    
    /** *************** *********** *************** **/

    private void addChart(Chart chart){
    	if ( ! listOfCharts.contains(chart) )
    		listOfCharts.add(chart);
    }

    /**
     * Method used to initialize all UI elements
     */
	protected void initUI(){
	    setContentView(R.layout.history);
	    Log.d(getLogTag(), "initUI");	    

		listOfCharts    = new ArrayList<Chart>();

	    type = (History)this.getIntent().getExtras().getSerializable(History.class.toString());

	    chartGallery		= (Gallery) findViewById(R.id.history_charts_galery);
	    averageLabel 		= (TextView)findViewById(R.id.history_stats_average);
	    totalLabel 			= (TextView)findViewById(R.id.history_stats_total);
	    costLabel 			= (TextView)findViewById(R.id.history_stats_cost);
	    historyTitle		= (TextView)findViewById(R.id.history_stats_title);
	    chartTitle			= (TextView)findViewById(R.id.history_charts_title);
	    homeButton			= (Button)findViewById(R.id.history_home_button); 
	    showStatButton		= (Button)findViewById(R.id.history_other_button);

	    int SCREEN_WIDTH  = this.getWindow().getWindowManager().getDefaultDisplay().getWidth();
	    int SCREEN_HEIGHT = this.getWindow().getWindowManager().getDefaultDisplay().getHeight();

	    Chart.defineChartDefaultSize(SCREEN_WIDTH, SCREEN_HEIGHT);

        if ( type.isWeekly() ){
        	historyTitle.setText(R.string.history_weekly_title);
        	showStatButton.setText(getResources().getString(R.string.home_month_stat_button_label));
        }else if(type.isMonthly()){
        	historyTitle.setText(R.string.history_monthly_title);
        	showStatButton.setText(getResources().getString(R.string.home_week_stat_button_label));
        }
	}

    /**
     * init Values ( not UI ) for this activiry from DB / Network / etc.
     */
	protected void initValues(){
		Log.d(getLogTag(), "initValues");

		if ( type.isWeekly() ){

			average 		= db.getWeeklyAdapter().getAverage();
			cost 			= db.getWeeklyAdapter().getCost();
			total 			= db.getWeeklyAdapter().getCount();
			
			showWeeklyDetailChart(db.getWeeklyAdapter().getDetails(), 		getResources().getString(R.string.history_week_detail_label));
			showWeeklyDetailChart(db.getWeeklyAdapter().getPreviousDetails(),getResources().getString(R.string.history_week_prev_detail_label));
			showWeeklyHistoryChart(db.getWeeklyAdapter().getHistoryAverage());        	
		
		}else if(type.isMonthly()){
			average 		= db.getMonthlyAdapter().getAverage();
			cost 			= db.getMonthlyAdapter().getCost();
			total 			= db.getMonthlyAdapter().getCount();
 
			showMonthlyDetailChart(db.getMonthlyAdapter().getDetails());
			showMonthlyDetailChart(db.getMonthlyAdapter().getPreviousDetails());
			showMonthlyHistoryChart(db.getMonthlyAdapter().getHistoryAverage(), 	getResources().getString(R.string.history_month_histo_label));
			showMonthlyHistoryChart(db.getMonthlyAdapter().getHistoryCost(), 	getResources().getString(R.string.history_month_cost_label));
		}

		chartImageAdapter = new ImageAdapter(HistoryActivity.this);
		chartImageAdapter.init();

	}

    /**
     * Method used to update the UI after called to initValues()
     */
	public void updateUI(){
    Log.d(getLogTag(), "updateUI");
    chartGallery.setAdapter(chartImageAdapter);
    
    String cigarette = getResources().getString(R.string.cigarette);
    String day = getResources().getString(R.string.day);
    
    String averageValueLabel = getResources().getString(R.string.history_average_label)+" "+average+" "+cigarette+" / "+day;    	
    averageLabel.setText(averageValueLabel);
    
    String totalValueLabel = getResources().getString(R.string.history_total_label)+" "+total+" "+cigarette;    	
    totalLabel.setText(totalValueLabel);
    
    String costValueLabel = getResources().getString(R.string.history_cost_label);
    NumberFormat ccyNF = NumberFormat.getCurrencyInstance(Locale.getDefault());
    costLabel.setText(costValueLabel+" "+ccyNF.format(cost));
	}

	/**
	 * Method used to generate the Monthly Detailed Chart
	 */
    protected void showMonthlyDetailChart(TreeMap<Integer, SmokeCounter> countValues){
    	Log.d(getLogTag(), "showMonthlyDetailChart");

    	/* Generate Data for chart (if available) */
    	if ( countValues.size() > 0 ){

        int nbDaysWithValues = 0;
        int lastDayOfMonth = 31;
        int detailsMaxValue = -1;
        int month = -1;

        LineChart lc = new LineChart();

         SmokeCounter firstSmoke = countValues.get(countValues.firstKey());
    		month = firstSmoke.getDate().get(Calendar.MONTH);
    		
    		lastDayOfMonth = Tools.getLastDayOfMonth(firstSmoke.getDate().get(Calendar.MONTH)/*-1*/);

    		int total = 0;

    		for ( int i = 1 ; i <= lastDayOfMonth; i++ ){

	    		if ( countValues.containsKey(i) ){	
	    			// Donnée dispo
	        		SmokeCounter smoke = countValues.get(i);
	    			lc.addDataValue(smoke.getValue());
	
	    			total += smoke.getValue();
	    			nbDaysWithValues++;
	    			
	            	if ( smoke.getValue() > detailsMaxValue )
	            		detailsMaxValue = smoke.getValue();
	
	    		}else {
	    			// Pas de données pour ce jour
					lc.addDataValue(Chart.BLANK_VALUE);
	    		}
    		}

          double currentAvg = total / nbDaysWithValues;
          
          /* Create the chart and define all parameters */
          lc.setAvgLegend(getResources().getString(R.string.history_month_average_legend));
          lc.setValueLegend(getResources().getString(R.string.history_month_value_legend));
          lc.setMaxYValue(detailsMaxValue);
          lc.setMaxXValue(lastDayOfMonth);
          lc.setAverage(currentAvg);
          lc.setTitle(getResources().getString(R.string.history_month_detail_label)+" "+Tools.getMonthLabel(this, (month+1)));
          
          //listOfCharts.add(lc);
          addChart(lc);

    	}else 
    		Log.d(getLogTag(), "No data to display ...");
    }

    /**
	 * Method used to generate the Monthly History Chart
	 */
    protected void showMonthlyHistoryChart(ArrayList<SmokeAverage> averageValues, String title){
    	Log.d(getLogTag(), "showMontlhyHistoryChart");
    	
    	if ( averageValues.size() > 0 ){

    		/* Create the chart and define all parameters */
        	HistoChart hst = new HistoChart();

        	double histoMaxValue = -1;

        	for (SmokeAverage smoke : averageValues){
        		hst.addDataValue(smoke.getValue());
        		hst.addColumnLabel(Tools.getMonthFirstLetter(this, Integer.valueOf(smoke.getLabel()) ));

        		if ( smoke.getValue() > histoMaxValue )
        			histoMaxValue = smoke.getValue();
        	} 
            
            hst.setMaxVal( new BigDecimal(histoMaxValue).intValue()+1);
            hst.setTitle(title);
            
            addChart(hst);
            //listOfCharts.add(hst);
    		
    	}else 
    		Log.d(getLogTag(), "No data to display ...");
    }

    
    /**
	 * Method used to generate the Weekly Detailed Chart
	 */
    protected void showWeeklyDetailChart(TreeMap<Integer, SmokeCounter>/*ArrayList<SmokeCounter>*/ countValues, String title){
    	Log.d(getLogTag(), "showWeeklyDetailChart");
    	
    	if ( countValues.size() > 0 ){
    		
        	int detailsMaxValue = -1;

        	/* Create the chart and define all parameters */
        	HistoChart hst = new HistoChart();

        	for (SmokeCounter smoke : countValues.values()){
        		hst.addDataValue(smoke.getValue());
        		hst.addColumnLabel(Tools.getDayFirstLetter(this, Integer.valueOf(smoke.getLabel()) ));
            	if ( smoke.getValue() > detailsMaxValue )
            		detailsMaxValue = smoke.getValue();
        	}

            hst.setMaxVal( new BigDecimal(detailsMaxValue).intValue()+1);
            hst.setBarColor("3072F3");
            hst.setTitle(title);
            
            //listOfCharts.add(hst);
            addChart(hst);
    
    	}else 
    		Log.d(getLogTag(), "No data to display ...");
    }
    
    /**
	 * Method used to generate the Weekly History Chart
	 */
    protected void showWeeklyHistoryChart(ArrayList<SmokeAverage> averageValues){
    	Log.d(getLogTag(), "showWeeklyHistoryChart");

    	if ( averageValues.size() > 0 ){
    		
        	double histoMaxValue = -1;
        	
        	/* Create the chart and define all parameters */
        	HistoChart hst = new HistoChart();

        	for (SmokeAverage smoke : averageValues){
            	hst.addDataValue(smoke.getValue());
        		hst.addColumnLabel(smoke.getLabel());
        		if ( smoke.getValue() > histoMaxValue )
            		histoMaxValue = smoke.getValue();
        	}

            hst.setMaxVal( new BigDecimal(histoMaxValue).intValue()+1);
            hst.setTitle(getResources().getString(R.string.history_week_histo_label));
                   
            //listOfCharts.add(hst);
            addChart(hst);
            
    	}else 
    		Log.d(getLogTag(), "No data to display ...");
    }    

    /** ************************************************************** **/
    /** ************************************************************** **/
    /** ************************************************************** **/
    
    class ImageAdapter extends BaseAdapter {

    	private Context mContext;
    	private ImageView[] tabImgView;
    	private Drawable defaultDrawable;
    	private ImageView defaultView;

    	private boolean[] imgUpdatedOK;
    	private boolean loadComplete = false;

    	/**
    	 * Create a new image adapter for Chart view
    	 * @param c
    	 */
    	public ImageAdapter(Context c) {
    		Log.d(getLogTag(), "new ImageAdapter()");
    		mContext = c;

    		defaultView = new ImageView(mContext);
    		defaultDrawable = getResources().getDrawable(R.drawable.eryos);
    		defaultView.setImageDrawable(defaultDrawable);
    	}

    	public void init(){
    		tabImgView = new ImageView[listOfCharts.size()];
    		imgUpdatedOK = new boolean[listOfCharts.size()];

    		for ( int i = 0 ; i < tabImgView.length ; i++){
    			tabImgView[i] = new ImageView(mContext);
    			tabImgView[i].setImageDrawable(defaultDrawable);
    			imgUpdatedOK[i] = false;
    		}    		
    	}
    	
    	/**
    	 * 
    	 */
    	public View getView(final int position, View convertView, ViewGroup parent) {
    		Log.d(getLogTag(), "getView : "+position+"/"+tabImgView.length);

    		if ( position < tabImgView.length && ! imgUpdatedOK[position] && ! loadComplete ) {
        		Log.d(getLogTag(), "getView - download : "+position);

        		try {
					Bitmap thumb = Chart.downloadChartAsBitmap(mContext, listOfCharts.get(position).getThumbURL()/*chartOverviewURL[position]*/); // mImageURLs
					listOfCharts.get(position).setThumbBitmap(thumb);
					tabImgView[position].setImageBitmap(thumb);
					imgUpdatedOK[position] = true;
					tabImgView[position].setLayoutParams(new Gallery.LayoutParams(Chart.DEFAULT_THUMB_WIDTH, Chart.DEFAULT_THUMB_HEIGHT));
					checkLoadComplete();
				} catch (UnknownHostException e) {
					e.printStackTrace();
				} catch (IOException e) {
					e.printStackTrace();
				}

    		}else {
        		Log.d(getLogTag(), "getView - bitmap already downloaded : "+position);
    		}
    		return tabImgView[position];
    	}

    	public int getCount() {
    		Log.d(getLogTag(), "getCount: "+listOfCharts.size());
    		return listOfCharts.size();
    	}

    	public Object getItem(int position) {
    		Log.d(getLogTag(), "getItem: "+position);
    		return tabImgView[position];//position;
    		//return position;
    	}

    	public long getItemId(int position) {
    		Log.d(getLogTag(), "getItemId: "+position);
    		return position;
    	}   
    	
    	public boolean isEnabled(int position){
    		Log.d(getLogTag(), "isEnabled: "+position+" : "+super.isEnabled(position));
    		return super.isEnabled(position);
    	}
    	
    	public int getViewTypeCount(){
    		Log.d(getLogTag(), "getViewTypeCount: "+super.getViewTypeCount());
    		return super.getViewTypeCount();
    	}
    	
    	public View getDropDownView(int position, android.view.View convertView, android.view.ViewGroup parent){
    		Log.d(getLogTag(), "getDropDownView: "+position);
    		return super.getDropDownView(position, convertView, parent);
    	}
    	
    	public int getItemViewType(int position){
    		Log.d(getLogTag(), "getItemViewType: "+position);
    		return super.getItemViewType(position);
    	}
    	
    	  
    	  

    	public void checkLoadComplete(){
    		boolean res = true;
    		for ( boolean load : imgUpdatedOK )
    			res = (res && load);

    		Log.d(getLogTag(), "checkLoadComplete : "+res);

    		if ( res )
    			hideWaitingMessage();
    	}
    }

	/**
	 * Method used to defined all UI handlers
	 */
	public void initHandlers(){
		Log.d(getLogTag(), "initHandlers");
		chartGallery.setOnItemSelectedListener(new OnItemSelectedListener(){
			public void onItemSelected(AdapterView<?> arg0, View arg1, int position, long id) {
				chartTitle.setText(listOfCharts.get(position).getTitle());
			}
			public void onNothingSelected(AdapterView<?> arg0) { }
        });
        
        chartGallery.setOnItemClickListener(new OnItemClickListener() {
            @SuppressWarnings("rawtypes")
			public void onItemClick(AdapterView parent, View v, int position, long id) {
            	new ChartPopup(HistoryActivity.this, listOfCharts.get(position));
            }
        });
        
        showStatButton.setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
                if ( type.isWeekly() ){
                	showView(VIEW.MONTHLY);
                }else if(type.isMonthly()){
                	showView(VIEW.WEEKLY);
                }
            }
        });
        
        homeButton.setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
            	showView(VIEW.HOME);
            }
        });
	}

	@Override
	public void hideWaitingMessageAfterLoad(){
		Log.d("HistoryActivity", "overriden HideWaitingMessage");
		hideWaitingMessage();
	}
}
